<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Web Component Example 4: Attributes and Lifecycle</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            flex-direction: column;
            gap: 20px;
            padding: 20px;
        }
        .controls button {
            padding: 8px 15px;
            margin-right: 10px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <h1>自定义属性和生命周期回调</h1>

    <div class="controls">
        <button onclick="changeCount()">改变第一个计数器的 count 属性</button>
        <button onclick="removeFirstCounter()">移除第一个计数器</button>
        <button onclick="addCounter()">添加新的计数器</button>
    </div>

    <!-- 带有初始 count 属性的计数器 -->
    <my-counter count="5"></my-counter>
    <my-counter count="10" step="2"></my-counter>
    <my-counter></my-counter> <!-- 没有 count 属性，会使用默认值 -->

    <script>
        const counterTemplate = document.createElement('template');
        counterTemplate.innerHTML = `
            <style>
                .counter-box {
                    border: 1px solid #007bff;
                    padding: 15px;
                    border-radius: 5px;
                    text-align: center;
                    display: inline-block;
                    margin-top: 10px;
                    min-width: 150px;
                }
                .counter-box p {
                    font-size: 2em;
                    color: #333;
                    margin: 5px 0;
                }
                .counter-box button {
                    background-color: #007bff;
                    color: white;
                    border: none;
                    padding: 8px 15px;
                    border-radius: 4px;
                    cursor: pointer;
                    font-size: 1em;
                    margin: 0 5px;
                }
                .counter-box button:hover {
                    opacity: 0.9;
                }
            </style>
            <div class="counter-box">
                <p>计数: <span id="current-count">0</span></p>
                <button id="decrement">-</button>
                <button id="increment">+</button>
            </div>
        `;

        class MyCounter extends HTMLElement {
            // 1. 声明要观察的属性
            static get observedAttributes() {
                return ['count', 'step'];
            }

            constructor() {
                super();
                this.attachShadow({ mode: 'open' });
                this.shadowRoot.appendChild(counterTemplate.content.cloneNode(true));

                // 初始内部状态
                this._count = 0;
                this._step = 1;

                // 缓存 DOM 元素引用
                this.$countDisplay = this.shadowRoot.getElementById('current-count');
                this.$decrementBtn = this.shadowRoot.getElementById('decrement');
                this.$incrementBtn = this.shadowRoot.getElementById('increment');

                console.log('MyCounter: 构造函数被调用！');
            }

            // 2. 当元素被添加到 DOM 时调用
            connectedCallback() {
                console.log('MyCounter: 元素被添加到DOM！');
                // 从 HTML 属性获取初始值，如果没有则使用默认值
                this._count = parseInt(this.getAttribute('count')) || 0;
                this._step = parseInt(this.getAttribute('step')) || 1;
                this._updateDisplay();

                // 添加事件监听器
                this.$decrementBtn.addEventListener('click', this._decrement);
                this.$incrementBtn.addEventListener('click', this._increment);
            }

            // 3. 当元素从 DOM 中移除时调用，进行清理工作
            disconnectedCallback() {
                console.log('MyCounter: 元素从DOM中移除！');
                // 移除事件监听器，防止内存泄漏
                this.$decrementBtn.removeEventListener('click', this._decrement);
                this.$incrementBtn.removeEventListener('click', this._increment);
            }

            // 4. 当观察的属性发生变化时调用
            attributeChangedCallback(name, oldValue, newValue) {
                console.log(`MyCounter: 属性 "${name}" 从 "${oldValue}" 变为 "${newValue}"`);
                if (oldValue !== newValue) {
                    if (name === 'count') {
                        this._count = parseInt(newValue) || 0;
                    } else if (name === 'step') {
                        this._step = parseInt(newValue) || 1;
                    }
                    this._updateDisplay();
                }
            }

            // 内部方法：更新显示
            _updateDisplay = () => { // 使用箭头函数保持 this 上下文
                this.$countDisplay.textContent = this._count;
            }

            // 内部方法：递减计数
            _decrement = () => {
                this._count -= this._step;
                this._updateDisplay();
                // 可以通过设置属性来触发 attributeChangedCallback (如果观察了_count)
                // this.setAttribute('count', this._count);
            }

            // 内部方法：递增计数
            _increment = () => {
                this._count += this._step;
                this._updateDisplay();
                // this.setAttribute('count', this._count);
            }

            // 可以定义公有属性来方便外部JS操作
            set count(value) {
                this.setAttribute('count', value); // 设置属性时，更新 HTML attribute
            }

            get count() {
                return this._count;
            }
        }

        customElements.define('my-counter', MyCounter);

        // 外部 JavaScript 函数，用于演示操作
        function changeCount() {
            const firstCounter = document.querySelector('my-counter');
            if (firstCounter) {
                const newCount = Math.floor(Math.random() * 100);
                firstCounter.setAttribute('count', newCount); // 改变 HTML 属性
                // 或者直接通过 JS 属性改变 (如果你定义了 setter)
                // firstCounter.count = newCount;
            }
        }

        function removeFirstCounter() {
            const firstCounter = document.querySelector('my-counter');
            if (firstCounter) {
                firstCounter.remove(); // 移除元素，会触发 disconnectedCallback
            }
        }

        let counterIndex = 0;
        function addCounter() {
            const newCounter = document.createElement('my-counter');
            newCounter.setAttribute('count', 100 + counterIndex++);
            document.body.appendChild(newCounter);
        }
    </script>
</body>
</html>
